/*
     Copyright (C) 2011 Benny Mackney

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "Box.h"
Box::Box()
{
    //ctor
    boxRect = {0,0,1,1};//Defines the position/dimensions of the box or position of the sprite
    clipRect = {0,0,1,1};//Define the clipping mask of the sprite
    boxColour = {255,255,255,255};
    sprite = NULL;
    modes = {0};

}

Box::~Box()
{
    //dtor
    if(sprite and get_mode(BSC_BOXMODE_FREESPRITE)){
        SDL_FreeSurface(sprite);
    }
}

void Box::draw_object(SDL_Surface* screen,SDL_Rect camera){
    //where are we drawing?
    SDL_Rect drawRect;
    drawRect.w = boxRect.w;
    drawRect.h = boxRect.h;
    if(get_mode(BSC_BOXMODE_DRAWCENTERED)){
        drawRect.x = boxRect.x-camera.x-boxRect.w/2;
        drawRect.y = boxRect.y-camera.y-boxRect.h/2;
    }else{
        drawRect.x = boxRect.x-camera.x;
        drawRect.y = boxRect.y-camera.y;
    }
    //Could we even be seen?
    if(!collides(&camera)){return;}
    //actually draw all that
    if(sprite!=NULL){
        SDL_BlitSurface(sprite,&clipRect,screen,&drawRect);
    }else{
        SDL_FillRect(screen, &drawRect, *((Uint32*)&boxColour) );
    }
}
void Box::set_x(Sint16 x){
    boxRect.x = x;
}
void Box::set_y(Sint16 y){
    boxRect.y = y;
}
void Box::set_pos(const Sint16 x, const Sint16 y){
    boxRect.x = x;
    boxRect.y = y;
}
void Box::set_w(Uint16 w){
    boxRect.w = w;
}
void Box::set_h(Uint16 h){
    boxRect.h = h;
}
void Box::set_dimensions(Uint16 w,Uint16 h){
    boxRect.w = w;
    boxRect.h = h;
}

int Box::load_sprite(const char* path){
    if(sprite){
        SDL_FreeSurface(sprite);
    }
    sprite = IMG_Load(path);
    if(sprite==NULL){
        return 1;
    }
    clipRect.w = sprite->w;
    clipRect.h = sprite->h;
    boxRect.w = sprite->w;
    boxRect.h = sprite->h;

    return 0;
}

int Box::set_sprite(SDL_Surface* newSprite){
    sprite = newSprite;
    clipRect.w = sprite->w;
    clipRect.h = sprite->h;
    return 0;
}

void Box::tick(){
    return;
}

void Box::set_mode(int mode, bool val){
    if(mode>BSC_BOX_NUMBEROFMODES){
        return;
    }
    modes[mode]=val;
}
bool Box::get_mode(int mode) const {
    if(mode>BSC_BOX_NUMBEROFMODES){
        return false;
    }
    return modes[mode];
}

void Box::set_colour(int r, int g, int b){
    boxColour = {b,g,r,0xFF};
}

void Box::set_colour(SDL_Colour colour){
    boxColour = colour;
}

Sint16 Box::get_x() const {
    return boxRect.x;
}

Sint16 Box::get_y() const {
    return boxRect.y;
}

Sint16 Box::get_x1() const {
    if(get_mode(BSC_BOXMODE_DRAWCENTERED)){
        return boxRect.x-boxRect.w/2;
    }
    return boxRect.x;
}

Sint16 Box::get_y1() const {
    if(get_mode(BSC_BOXMODE_DRAWCENTERED)){
        return boxRect.y-boxRect.h/2;
    }
    return boxRect.y;
}

Sint16 Box::get_x2() const {
    if(get_mode(BSC_BOXMODE_DRAWCENTERED)){
        return boxRect.x+boxRect.w/2;
    }
    return boxRect.x+boxRect.w;
}

Sint16 Box::get_y2() const {
    if(get_mode(BSC_BOXMODE_DRAWCENTERED)){
        return boxRect.y+boxRect.h/2;
    }
    return boxRect.y+boxRect.h;
}

bool Box::collides(const Box * collider) const {
    if((get_x2() < collider->get_x1()) ||
	   (get_x1() > collider->get_x2()) ||
	   (get_y1() > collider->get_y2()) ||
	   (get_y2() < collider->get_y1())){
	   	return false;
	}else{
		return true;
	}
}

bool Box::collides(const SDL_Rect* collider) const {
    if((get_x2() < collider->x) ||
	   (get_x1() > (collider->x+collider->w)) ||
	   (get_y1() > (collider->y+collider->h)) ||
	   (get_y2() < collider->y)){
	   	return false;
	}else{
		return true;
	}
}
